web 存储机制
# web 存储机制
Web Storage的两个主要目标: 提供一种在cookie之外存储会话数据的途径。 提供一种存储大量可以跨会话存在的数据的机制。
[TOC]
# 一、Storage 类型
# 二、sessionStorage 对象
关闭选项卡后,将删除存储在
sessionStorage
中的数据。作用域:同一浏览器+同源文档+同一窗口,才能共享数据,互相读取和覆盖。
- 例如你在浏览器中打开了两个相同地址的页面A、B,虽然这两个页面的源完全相同,但是他们还是不能共享数据,因为他们是不同窗口中的。但是如果是一个窗口中,有两个同源的
iframe
元素的话,这两个iframe
的 sessionStorage 是可以互通的。
- 例如你在浏览器中打开了两个相同地址的页面A、B,虽然这两个页面的源完全相同,但是他们还是不能共享数据,因为他们是不同窗口中的。但是如果是一个窗口中,有两个同源的
# 三、globalStorage 对象
# 四、localStorage 对象
如果使用
localStorage
,数据将永远存在,除非例如调用localStorage.clear()
。作用域:同一浏览器+同源文档,就能共享数据。
# 4.1 API
localStorage 和 sessionStorage 有着统一的API接口。
- 获取数据:
localStorage.getItem(key,value)
- 设置数据:
localStorage.setItem(key,value)
- 删除数据:
localStorage.removeItem(key)
- 清空所有数据:
localStorage.clear()
- 获取本地存储数据数量:
localStorage.length
# 五、storage 事件
# 六、其他
# 6.1 cookies,session, sessionStroage和localStorage的区别
cookies,sessionStroage和localStorage是在客户端,session是在服务器端。
- 服务器端的session机制, session 对象数据保存在服务器上。实现上,服务器和浏览器之间仅需传递session id即可,服务器根据session id找到对应用户的session对象。
- 会话数据仅在一段时间内有效,这个时间就是server端设置的session有效期。
- 服务器session存储数据安全一些,一般存放用户信息,浏览器只适合存储一般数据。
cookies,sessionStroage和localStorage三者的区别
特性 Cookie localStorage sessionStorage 数据的生命期 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 除非被清除,否则永久保存 仅在当前会话下有效,关闭页面或浏览器后被清除,刷新不会被清除 存放数据大小 4K左右 一般为5MB 👈
| 与服务器端通信 | 每次都会携带在HTTP请求头中,如果使用cookie保存过多数据会带来性能问题 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 | 👈 | - Web storage 支持事件通知机制,可以将数据更新的通知发送给监听者。
```js
window.addEventListener("storage", function (e) {
alert(e.newValue);
});
```
# 应用场景
有了对上面这些差别的直观理解,我们就可以讨论三者的应用场景了。
因为考虑到每个 HTTP 请求都会带着 Cookie 的信息,所以 Cookie 当然是能精简就精简啦,比较常用的一个应用场景就是判断用户是否登录。针对登录过的用户,服务器端会在他登录时往 Cookie 中插入一段加密过的唯一辨识单一用户的辨识码,下次只要读取这个值就可以判断当前用户是否登录啦。曾经还使用 Cookie 来保存用户在电商网站的购物车信息,如今有了 localStorage,似乎在这个方面也可以给 Cookie 放个假了~
而另一方面 localStorage 接替了 Cookie 管理购物车的工作,同时也能胜任其他一些工作。比如HTML5游戏通常会产生一些本地数据,localStorage 也是非常适用的。如果遇到一些内容特别多的表单,为了优化用户体验,我们可能要把表单页面拆分成多个子页面,然后按步骤引导用户填写。这时候 sessionStorage 的作用就发挥出来了。
# 安全性的考虑
需要注意的是,不是什么数据都适合放在 Cookie、localStorage 和 sessionStorage 中的。使用它们的时候,需要时刻注意是否有代码存在 XSS 注入的风险。因为只要打开控制台,你就随意修改它们的值,也就是说如果你的网站中有 XSS 的风险,它们就能对你的 localStorage 肆意妄为。所以千万不要用它们存储你系统中的敏感数据。
Web Storage的好处
减少网络流量
- 一旦数据保存在本地后,就可以避免再向服务器请求数据,因此减少不必要的数据请求,减少数据在浏览器和服务器间不必要地来回传递。
快速显示数据
- 性能好,从本地读数据比通过网络从服务器获得数据快得多,本地数据可以即时获得。再加上网页本身也可以有缓存,因此整个页面和数据都在本地的话,可以立即显示。
临时存储
- 很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用sessionStorage非常方便。
# 6.2 IndexDB
参考教程:
浏览器数据库 IndexedDB 入门教程 (opens new window)
- 一个运行在浏览器上的非关系型数据库,理论上没有存储上限;可以存储字符串,还可以储存二进制数据。
// 打开数据库
var request = window.indexedDB.open('test', 1);
var db;
request.onerror = function (event) {
console.log('数据库打开报错');
};
request.onsuccess = function (event) {
db = request.result;
console.log('数据库打开成功');
};
// 当你创建一个新的数据库或者增加已存在的数据库的版本号(当打开数据库时,指定一个比之前更大的版本号), onupgradeneeded 事件会被触发
request.onupgradeneeded = function (event) {
db = event.target.result;
var objectStore;
if (!db.objectStoreNames.contains('person')) {
objectStore = db.createObjectStore('person', { keyPath: 'id' });
objectStore.createIndex('name', 'name', { unique: false }); // 建立索引,方便找东西
objectStore.createIndex('email', 'email', { unique: true });
}
}
// 新增数据
// add() 保存的主键已存在,则保存失败
// put() 保存的主键已存在,则修改对象
function add() {
var request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.put({ id: 1, name: '张三', age: 24, email: 'zhangsan@example.com' });
request.onsuccess = function (event) {
console.log('数据写入成功');
};
request.onerror = function (event) {
console.log('数据写入失败');
}
}
// 读取数据
function read() {
var transaction = db.transaction(['person']);
var objectStore = transaction.objectStore('person');
var request = objectStore.get(1); // 参数是主键的值
request.onerror = function(event) {
console.log('事务失败');
};
request.onsuccess = function( event) {
if (request.result) {
console.log("读取的数据",request.result)
} else {
console.log('未获得数据记录');
}
};
}
read();
// 遍历数据
function readAll() {
var objectStore = db.transaction('person').objectStore('person');
objectStore.openCursor().onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
console.log("遍历的数据",cursor.value)
cursor.continue();
} else {
console.log('没有更多数据了!');
}
};
}
readAll();
// 更新数据
function update() {
var request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.put({ id: 1, name: '李四', age: 35, email: 'lisi@example.com' });
request.onsuccess = function (event) {
console.log('数据更新成功');
};
request.onerror = function (event) {
console.log('数据更新失败');
}
}
update();
// 删除数据
function remove() {
var request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.delete(1);
request.onsuccess = function (event) {
console.log('数据删除成功');
};
}
remove();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107